#include "board_config.h"
#include "stm32f1xx.h"
#include "sys_types.h"

void _hal_clk_init(u8_t PLL)
{
    /* 配置 MCU 时钟 */
    u8_t temp = 0;
    RCC->CR |= 0x00010000;   // 外部高速时钟使能HSEON
    while (!(RCC->CR >> 17)) // 等待外部时钟就绪
    {
    }

    RCC->CFGR = 0X00000400; // APB1=DIV2;APB2=DIV1;AHB=DIV1;
    PLL -= 2;               // 抵消2个单位
    RCC->CFGR |= PLL << 18; // 设置PLL值 2~16
    RCC->CFGR |= 1 << 16;   // PLLSRC ON
    FLASH->ACR |= 0x32;     // FLASH 2个延时周期

    RCC->CR |= 0x01000000;   // PLLON
    while (!(RCC->CR >> 25)) // 等待PLL锁定
    {
    }

    RCC->CFGR |= 0x00000002; // PLL作为系统时钟
    while (temp != 0x02)     // 等待PLL作为系统时钟设置成功
    {
        temp = RCC->CFGR >> 2;
        temp &= 0x03;
    }
    SystemCoreClock = 8000000 * (PLL + 2);
}

__weak void SystemInit(void)
{
    /* 设置 MCU 的中断向量和中断分组 */
    if (SCB->VTOR == 0)
    {
        SCB->VTOR = 0x08000000;
    }
    NVIC_SetPriorityGrouping(0);
    _hal_clk_init(9);
}

void drv_hal_init(void)
{
    /* sys clk */
    do
    {
        _hal_clk_init(9);
        SystemCoreClockUpdate();
    } while (0);

    /* GPIO */
    do
    {
        drv_gpio_enable_all();
    } while (0);

    /* console */
    do
    {
#define BAUD 4500000
        RCC->APB2ENR |= 1 << 2;                            // 使能PORTA口时钟
        RCC->APB2ENR |= 1 << 14;                           // 使能串口时钟
        GPIOA->CRH &= 0XFFFFF00F;                          // IO状态设置
        GPIOA->CRH |= 0X000008B0;                          // IO状态设置
        RCC->APB2RSTR |= 1 << 14;                          // 复位串口1
        RCC->APB2RSTR &= ~(1 << 14);                       // 停止复位
        USART1->BRR = (72000000 / 16 + (BAUD / 2)) / BAUD; // 波特率设置
        USART1->CR1 |= 0X200C;                             // 1位停止,无校验位.

    } while (0);
}

void drv_hal_debug_enable(void)
{
}

void drv_hal_debug_disable(void)
{
}

void drv_hal_sys_reset(void)
{
    NVIC_SystemReset();
}
